package campus.aiit.ssl.service;

import campus.aiit.ssl.dao.DeviceDao;
import campus.aiit.ssl.dao.StrategyDao;
import campus.aiit.ssl.dao.WeekDao;
import campus.aiit.ssl.domain.model.Device;
import campus.aiit.ssl.domain.model.Strategy;
import campus.aiit.ssl.domain.model.Week;
import campus.aiit.ssl.manage.custom.dao.DaoProxy;
import campus.aiit.ssl.manage.modbus.ModBus;
import campus.aiit.ssl.manage.modbus.ModBusCommand;
import campus.aiit.ssl.manage.modbus.SocketForModBus;
import campus.aiit.ssl.manage.modbus.provider.Provider;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author ihaokun
 * @date 2019/12/24 9:25
 */
@Service
public class StrategyService {
  @Resource
  private ModBusCommand cmd;

  private DeviceDao deviceDao;
  private StrategyDao strategyDao;
  private WeekDao weekDao;

  @Autowired
  public StrategyService(DeviceDao deviceDao, StrategyDao strategyDao, WeekDao weekDao) {
    this.deviceDao = new DaoProxy<DeviceDao>().getProxy(deviceDao);
    this.strategyDao = new DaoProxy<StrategyDao>().getProxy(strategyDao);
    this.weekDao = new DaoProxy<WeekDao>().getProxy(weekDao);
  }

  @Transactional
  public boolean addStrategy(Strategy strategy) {
    // Write strategy, week
    strategyDao.insertSelective(strategy);

    Strategy.Weeks weeks = strategy.getWeeks();
    Week week = new Week();
    BeanUtils.copyProperties(weeks, week);
    week.setStrategyId(strategy.getId());

    byte[] days = weeks.getDays();
    for (byte day : days) {
      week.setDay(day);
      hexContent(week);
      weekDao.insertSelective(week);
    }
    return true;
  }
  @Transactional
  public boolean saveStrategy(Strategy strategy) {
    strategyDao.updateByPrimaryKeySelective(strategy);
    weekDao.deleteByForeignKey(strategy.getId());
    Week week = new Week();
    BeanUtils.copyProperties(strategy.getWeeks(), week, "days");
    week.setStrategyId(strategy.getId());
    for (byte day : strategy.getWeeks().getDays()) {
      week.setDay(day);
      hexContent(week);
      weekDao.insertSelective(week);
    }
    return true;
  }
  public boolean saveDay(Week week) {
    hexContent(week);
    weekDao.updateByPrimaryKeySelective(week);
    return true;
  }
  private void hexContent(Week week){//crux
    String hexString = week.toHexString();
    week.setContent(hexString);
  }
  public boolean apply(long strategyId, long[] deviceIds) {
    List<Week> weeks = weekDao.selectByForeignKey(strategyId);
    List<Byte> days = new ArrayList<>();
    weeks.forEach(week -> { days.add(week.getDay()); });
    for (long deviceId : deviceIds) {
      Device device = deviceDao.selectByPrimaryKey(deviceId);
      SocketForModBus.SDU sdu = new SocketForModBus.SDU(device.getIpAddress(), device.getPort());
      ModBus.ADU adu = new ModBus.ADU();
      adu.setAddress(device.getAddressCode());
//      for (byte i = 1; i <= 7; i++) {
//        if (!days.contains(i)){
//          StringBuilder builder = new StringBuilder();
//          switch (i){
//            case 1:
//              builder.append(Provider.Constants.PDUs.MONDAY.getHex());
//              break;
//            case 2:
//              builder.append(Provider.Constants.PDUs.TUESDAY.getHex());
//              break;
//            case 3:
//              builder.append(Provider.Constants.PDUs.WEDNESDAY.getHex());
//              break;
//            case 4:
//              builder.append(Provider.Constants.PDUs.THURSDAY.getHex());
//              break;
//            case 5:
//              builder.append(Provider.Constants.PDUs.FRIDAY.getHex());
//              break;
//            case 6:
//              builder.append(Provider.Constants.PDUs.SATURDAY.getHex());
//              break;
//            case 7:
//              builder.append(Provider.Constants.PDUs.SUNDAY.getHex());
//              break;
//            default:
//              System.err.println("Fatal Error: day field not in [1, 7]");
//              break;
//          }
//          builder.append("00 00 00 00 00 00 00 00 00 00 00 00 00 00");
//          adu.setPdu(new ModBus.ADU.PDU(builder.toString()));
//          sdu.setAdu(adu);
//          for (int j=1;j<=10;j++ ){
//
//            String substring = adu.toString().substring(0, 6);
//            substring=substring+"0"+j+adu.toString().substring(8);
//
//            if (j==10){
//              substring = adu.toString().substring(0, 6);
//              substring=substring+"0A"+adu.toString().substring(8);
//            }
//
//            adu.setPdu(new ModBus.ADU.PDU(substring.substring(2,substring.substring(2).length()-2)));
//            sdu.setAdu(adu);
//
//
//            System.out.println("===================>"+adu);
//            cmd.writeStrategy(sdu);
//
//          }
//
//
//        }
//      }

      for (Week week : weeks) {
        String substring=null;
        String zero="00 00 00 00 00 00 00 00 00 00 00 00 00 00";
        for (int j = 1; j <=10 ; j++) {


          substring = week.getContent().substring(0, 3);
          substring=substring+week.getDay()+"0"+j+week.getContent().substring(6,12)+zero;

          if (j==1){
            substring = week.getContent().substring(0, 3);
            substring=substring+week.getDay()+"0"+j+week.getContent().substring(6);
          }


          if (j==10){
            substring = week.getContent().substring(0, 3);
            substring=substring+week.getDay()+"0A"+week.getContent().substring(6,12)+zero;

          }
          adu.setPdu(new ModBus.ADU.PDU(substring));
          sdu.setAdu(adu);


          System.out.println("===================>"+adu);
          cmd.writeStrategy(sdu);
        }

      }
    }
    return true;
  }

  public List<Strategy> strategies() {
    return strategyDao.selectAll(null);
  }
  public List<Week> weeks(long id) {
    return weekDao.selectByForeignKey(id);
  }

  @Transactional
  public boolean removeStrategy(long id) {
    weekDao.deleteByForeignKey(id);
    strategyDao.deleteByPrimaryKey(id);
    return true;
  }

  public List<Strategy> strategiesByAdmin() {
    return strategyDao.selectByRoleId(0);
  }

  public List<Strategy> strategiesByUser() {
    return null;
  }

  public  List<Map<String,Object>> getStrategyByTypeId(long deviceTypeId) {
    
    return weekDao.getStrategyByTypeId(deviceTypeId);
  }

  public int delCurrencyStrategy(long id) {
    return weekDao.delCurrencyStrategy(id);
  }

  public int updateCurrencyStrategy(Map map) {
    return weekDao.updateCurrencyStrategy(map);
  }

  public int addCurrencyStrategy(Map map) {
    return weekDao.addCurrencyStrategy(map);
  }
}